;›;**************************************›;›; THIS IS WHERE WE ENTER WHEN PROCESSOR›; IS RESET.›; PERIPHERAL DEVICES ARE INITIALIZED›; MEMORY IS CLEARED›; BACKGROUND PROCESSING, IF ANY IS›; STARTED›;›;**************************************›;›;›STARTLDX#$FF›TXS;SET THE STACK POINTER TO›;TOP OF STACK›JSRCLRMEM;CLEAR MEMORY›JSRCLRZER;CLEAR PAGE ZERO›;›LDA#$4C;LOAD JUMP INSTRUCTION›STAGET›STAPUT›LDASGVEC;SET UP SLOW GET VECTOR›STAGET+1›LDASGVEC+1›STAGET+2›LDASPVEC;SET UP SLOW PUT VECTOR›STAPUT+1›LDASPVEC+1›STAPUT+2›LDA#0›STADCKFLG;CHECK TRACK DENSITY›STACMDRT;SET COMMAND RETRYS TO 0›LDA#$FF›STASSTAT;SPEED STAT AT NORMAL›;›LDA#$FF›STAFDCFLG;HAVE NOT FOUND FDC TYPE›LDA#$82;READ SECTOR FOR 1793›STARSECCM›LDA#$A2;WRITE SECTOR FOR 1793›STAWSECCM›LDA#$A3;WRITE SECTOR WITH DM 1793›STAWSDMCM›;›LDA#108;INITIAL STEP RATE›STASRATE›;›LDA#LOW CMDNAK;INIT USER COMMAND›STACSELXX;DECODE VECTOR TO COMAND›LDA#HIGH CMDNAK;NAK›STACSELXX+1›LDA#$FF›STATINB›LDA#$10;MAX OF 16 SEC TIMEOUT›STASTAT+2›LDA#$10›STASTAT;TELL THE WORLD WE ARE HERE›;›LDA#$3C;SET PORT A FOR INPUT›STADDRA;USER MAY IF HE/SHE CHOOSES›LDA#$3D›STADDRB›LDA#%00111101›STASTPPOS›STADRB›LDA#$FF›STADRA›LDA#$FF›STATFLAG;PUT IN UNBUFFER MODE›;›LDA#40;DRIVE CONFIG INITIAL (STDRD)›STACONFIG;40 TRACKS PER SIDE›LDA#18›STACONFIG+3;18 SECTORS PER TRACK›LDA#128›STACONFIG+7›STALENTH;SECTOR LENGTH›LDA#$40›STACONFIG+8›;›LDA#10›STATL;INIT MOTOR HANGON TIME 1 SEC›;›CLD;CLEAR DECIMAL MODE››JSRMCK;TURN ON MOTOR›JSRTRK0;SEEK TRACK 0›LDA#15›STANTRK›JSRSKTK;SEEK TRACK 15›JSRTRK0;SEEK TRACK 0›;›; CHECK TO SEE IF THERE IS A DISK IN›; THE DRIVE›;›BITSTREG;CHECK FDC STATUS›BMISTRT01;DOOR OPEN›JSRCSSK;CHECK TO SEE WHAT FORMAT›;›;›STRT01JSRI5SEC;INIT 5 SECOND TIMER›;›BKGRNDPROC›;›:STATUS=$A0›;›LDA#2;BIT MASK›BITDRB;TEST CMD LINE›BPLBK001;CMD NOT HIGH›BNEBK004;COMPUTER NOT ON›JSRRCMDFRM;GET COMMAND FRAME›;›;ON RETURN, DO A COMPLETE RE-INIT OF›;THE TIMER IF STATUS = 0›;›LDA:STATUS;CHECK STATUS›BNEBK003›JSRI5SEC;RE INIT 5 SEC TIMER›JMPBK001›BK003LDA#97;.1 SEC INTERVAL›JSRSTMO;SET TIMER›JMPBK001›;›BK004LDASGVEC;SET UP SLOW VECTOR›STAGET+1›LDASGVEC+1›STAGET+2›LDASPVEC›STAPUT+1›LDASPVEC+1›STAPUT+2›;›;CONTINUE COUNTDOWN›;›BK001JSRDRCHK;CHECK DOOR STATUS›LDAMFLAG›BEQBKGRND›JSRCK5S;CHECK 5 SECOND TIMER›BCCBK002›JSRMOOFF;TURN OFF MOTOT›LDAWT64D›LDA#$00›STAMFLAG›BK002JMPBKGRND;JUMP TO BACKGROUND›;ROUTINE›EPROC›;›;›;**************************************›;›; DRCHK: CHECK DOOR STATUS›;›; ENTRY: NONE›; EXIT: NONE›; REGISTERS USED: ACCUMULATOR›;›;**************************************››DRCHKBITSTREG›BPLDRCHK1;DOOR CLOSED›BITDRCLSD›BPLDRCKXT;STILL OPEN, EXIT›LDA#0;JUST OPENED›STADRCLSD›JMPDRCKXT›DRCHK1BITDRCLSD›BMIDRCKXT;STILL CLOSED, EXIT›LDA#$FF;JUST CLOSED›STADRCLSD›JSRMCK;TURN ON MOTOR›JSRCSSK;CHECK THE FORMAT›JSRI5SEC›DRCKXTRTS›››;**************************************›;›; DELAY: ABOUT 250USEC›;›;**************************************›;›DELAYPHA;SAVE ACCUMULATOR›LDA#42›DEL01SEC›SBC#$01;DECREMANT ACC›BNEDEL01›PLA›RTS›;›;**************************************›;›; BTOG: BUAD RATE TOGGLE›;›; ENTRY:NONE›; EXIT:NONE›; BUAD RATE IS TOGGLED›;›;**************************************›;›BTOGPROC›;›LDASSTAT;LOAD SPEED STATUS›BNE:BTG01›LDASGVEC;SET UP SLOW GET VECTOR›STAGET+1›LDASGVEC+1›STAGET+2›LDASPVEC;SET UP SLOW PUT VECTOR›STAPUT+1›LDASPVEC+1›STAPUT+2›LDA#$FF›STASSTAT;SPEED STAT AT NORMAL›BNE:BTGXT›;›:BTG01LDAFGVEC;SET UP US GET VECTOR›STAGET+1›LDAFGVEC+1›STAGET+2›LDAFPVEC;SET UP US PUT VECTOR›STAPUT+1›LDAFPVEC+1›STAPUT+2›LDA#$0›STASSTAT;SPEED STAT AT US›:BTGXTRTS›;›;›;**************************************›;›; SGET: GET SLOW DATA FROM SERIAL BUS›;›; ENTRY:A-REG =# OF BYTES TO GET›; :BPNT CONTAIN ADDRESS OF BUFFER›; EXIT:DATA IN BUFFER›; :$A0 CONTAINS STAUTUS›; :$A1 CONTAINS CHECKSUM›;›; REGISTERS USED:ACCUMULATOR,X,Y›; :USES BPNT›;**************************************›;›SGETPROC›;›:STATUS=$A0›:CKSUM=$A1›;›STAGCNT;SAVE BYTE COUNT›LDY#$00›STYFLAG;INIT CHECKSUM FLAG›:GET01BITDRA;CHECK FOR TIME OUT›BVCDITOUT›BITDRB;WAIT FOR START BIT›BVC:GET01;LOOP IF NO OVERFLOW›SEC;SET CARRY›LDA#$80;A := $80›LDX#$06;›:GET02DEX;›BNE:GET02;DELAY LOOP›LB80LDX#$06;›:GET03DEX;›BNE:GET03;DELAY LOOP›NOP›NOP›NOP;TIMING›BITDRB›BVC:GET04;JMP AND SET CARRY›CLC›BCC:GET05;JMP WITH CARRY CLEAR›:GET04SEC›NOP›:GET05RORA›BCCLB80›LDXFLAG›BNE:GETXIT›STA(BPNT),Y›INY›CPYGCNT;DECREMENT BYTE COUNT›BNE:GET01;KEEP GOING, MORE DATA›LDX#$FF›STXFLAG;NOW WE GET THE CHECKSUM›BNE:GET01›:GETXITSTA:CKSUM;SAVE CHECKSUM›LDA#0›STA:STATUS›LDAWT64D›:GETXTRTS›;›;DO THIS IF THERE IS A TIMEOUT›;›DITOUTLDA#$01›STA:STATUS;TIMEOUT STATUS RETURNED›LDAWT64D›JMP:GETXT›EPROC;›SGVECDWSGET›;›;›;**************************************›;›; SPUT:›; SEND THE BYTE IN THE ACCUMULATOR›; TO THE ATARI COMPUTER SLOWLY›;›; ENTRY:A<-- BYTE TO SEND›; EXIT: NONE›;›; REGISTERS USED:ALL PRESERVED›;›;›;**************************************›;›;›SPUTPROC›;›:DATA=$A0;DATA TO TRANSMIT›:SAVEX=$A1;SAVE AREA FOR X REG›:SAVEY=$A2;SAVE AREA FOR Y REG›;›STA:DATA›STY:SAVEY›STX:SAVEX›LDY#$08›LDA#$FE›ANDDRB›STADRB›INC:SAVEX›PUT93ROR:DATA›BCCPUT90›LDA#$01›ORADRB›BNEPUT91›PUT90LDA#$FE›ANDDRB›NOP›PUT91LDX#$05›PUT92DEX›BNEPUT92›STADRB›DEY›BNEPUT93›LDX#$06›PUT94DEX›BNEPUT94›NOP›DEC:SAVEX›LDA#$01›ORADRB›STADRB›LDX#$05›PUT95DEX›BNEPUT95›LDX:SAVEX›LDA:DATA›LDY:SAVEY›RTS›EPROC›SPVECDWSPUT›;›;**************************************›;›; SET TIME OUT:›;›;**************************************›;›STMOSTAWT64D›STAWT24E›RTS›;›;**************************************›;›; ACK:›; SEND ACKNOLEGDE BACK TO ATARI›;›; ENTRY:NONE›; EXIT:NONE›;›; REGISTERS USED:›; ACCUMULATOR›;›;**************************************›;›ACKLDA#'A';LOAD ACK CODE›JSRPUT;SEND IT TO THE ATARI›RTS›;›;**************************************›;›; NAK:›; SEND NOT ACKNOLEGED BACK TO ATARI›;›; ENTRY:NONE›; EXIT:NONE›;›; REGISTERS USED:›; ACCUMULATOR›;›;**************************************›;›NAKLDA#'N';LOAD NAK CODE›JSRPUT;SEND IT TO THE ARARI›RTS›;›;**************************************›;›; ERR:›; SEND ERROR BACK TO ATARI›;›; ENTRY:NONE›; EXIT:NONE›;›; REGISTERS USED:A›;›;**************************************›;›ERRLDA#'E';LOAD ERROR CODE›JSRPUT;SEND IT TO THE ARARI›RTS›;›;**************************************›;›; CMPLT:›; SEND PROCESS COMPLETE CODE›;›; ENTRY: NONE›; EXIT: NONE›;›; REGISTERS USED:A›;›;**************************************›;›CMPLTLDA#'C';LOAD COMPLETE CODE›JSRPUT;SEND IT TO THE ATARI›RTS›;›;›;**************************************›;›; CSUM:›; COMPUTE THE CHECKSUM›;›; ENTRY:A CONTAINS VALUE TO ADD TO CSUM›; EXIT:NONE›;›;**************************************›;›CSUMPHA;SAVE ACCUMULATOR›CLC;PREPARE TO ADD›ADCCHKSUM›ADC#$00›STACHKSUM›PLA;RECOVER ORIGINAL VALUE›RTS›;›;**************************************›;›; CKSM:›;›; COMPUTE THE CHECKSUM ATARI STYLE›;›; ENTRY:X REG NUMBER OF VALUES TO CHK›; :BPNT=ADDRESS OF STRING›; :CHKSUM IS IN REG A›; EXIT:CARRY SET IF BAD CHECKSUM›;›; REGISTERS USED:A,X,Y›;›; MEMORY USE:›; ONE BYTE ON PAGE ZERO›; CHKSUM›;›;**************************************›;›CKSMPROC›;›:CHKSM=$A0›;›STA:CHKSM;SAVE CHECKSUM›STXGCNT;SET UP LOOP COUNTER›LDY#$00;ZERO INDEX›TYA;ZERO ACCUMULATOR›CKSM01CLC›ADC(BPNT),Y;SUM WITH CHECKSUM›ADC#$00;ADD CARRY IF ANY›INY›CPYGCNT;END OF STRING?›BNECKSM01›SEC›SBC:CHKSM;EQUAL TO CHECKSUM?›STA:CHKSM;RETURN 0 IF EQUAL›BEQ:EXIT›LDA#$02›STA:CHKSM;BAD CHECKSUM›:EXITRTS›EPROC›;›;**************************************›;›; CLRMEM:›; CLEAR MEMORY PAGES 2 TO $0F›;›; ENTRY:NONE›; EXIT:PAGES 2 TO 15 FILLED WITH $00›; ›; REGISTERS USED:A,X,Y›;›; MEMORY USED:2 BYTES PAGE ZERO›;›;**************************************›;›CLRMEMLDA#HIGH BUFF;ON PAGE ZERO TO POINT›STABPNT+1;TO MEMORY TO CLEAR›LDA#LOW BUFF;CLEAR ACCUM›STABPNT;SET UP INDIRECT POINTER›;›LDY#$00;INIT INDEX REGISTER›CLMEM1STA(BPNT),Y›INY;POINT TO NEXT BYTE›BNECLMEM1›INCBPNT+1;INC MEMORY POINTER›LDXBPNT+1›CPX#$40;END OF MEMORY TO CLEAR (2K)›BNECLMEM1;CONTINUE UNTILL DONE›RTS›;›;HIGH SPEED TRANSFER ROUTINES›;›;**************************************›;›; FGET: GET FAST DATA FROM SERIAL BUS›;›; ENTRY:A-REG =# OF BYTES TO GET›; :BPNT CONTAIN ADDRESS OF BUFFER›; EXIT:DATA IN BUFFER›; :$A0 CONTAINS STAUTUS›; :$A1 CONTAINS CHECKSUM›;›; REGISTERS USED:ACCUMULATOR,X,Y›; :USES BPNT›;**************************************›;›FGETPROC›;›:STATUS=$A0›:CKSUM=$A1›:DUMMY=$A8›;›STAGCNT;SAVE BYTE COUNT›TAX›LDY#$00›:FGET1BITDRA;4 CHECK FOR TIME OUT›BVC:TOUT;2›:FGET2BITDRB;4 WAIT FOR START BIT›BVC:FGET2;2 LOOP IF NO OVERFLOW›SEC;2 SET CARRY›LDA#$80;2 A := $80›NOP;2›NOP;2›NOP;2›NOP;2›STX:DUMMY;3›;›:LOOPSTX:DUMMY;3›BITDRB;4›BVC:FGET4;JMP AND SET CARRY›CLC›BCC:FGET5;JMP WITH CARRY CLEAR›:FGET4SEC›NOP›:FGET5RORA›BCC:LOOP›STA(BPNT),Y;STORE RECIEVED DATA›INY›DEX›BEQ:FGET9;END OF GET›JMP:FGET2;KEEP GOING, MORE DATA›;›;GET CHECKSUM›;›:FGET6BITDRA;4 CHECK FOR TIME OUT›BVC:TOUT;2›:FGET9BITDRB;4 WAIT FOR START BIT›BVC:FGET9;2 LOOP IF NO OVERFLOW›SEC;2 SET CARRY›LDA#$80;2 A := $80›NOP;2›NOP;2›NOP;2›NOP;2›STX:DUMMY;3›;›:LOOP1STX:DUMMY;3›BITDRB;4›BVC:FGET7;JMP AND SET CARRY›CLC›BCC:FGET8;JMP WITH CARRY CLEAR›:FGET7SEC›NOP›:FGET8RORA›BCC:LOOP1›;›STA:CKSUM;SAVE CHECKSUM›LDA#0›STA:STATUS›LDAWT64D›:GETXTRTS›;›;DO THIS IF THERE IS A TIMEOUT›;›:TOUTLDA#$01›STA:STATUS;TIMEOUT STATUS RETURNED›LDAWT64D›JMP:GETXT›EPROC;›FGVECDWFGET›;›;›;**************************************›;›; FPUT:›; SEND THE BYTE IN THE ACCUMULATOR›; TO THE ATARI COMPUTER SLOWLY›;›; ENTRY:A<-- BYTE TO SEND›; EXIT: NONE›;›; REGISTERS USED:ALL PRESERVED›;›;›;**************************************›;›;›FPUTPROC›;›:DATA=$A0;DATA TO TRANSMIT›:SAVEX=$A1;SAVE AREA FOR X REG›:SAVEY=$A2;SAVE AREA FOR Y REG›:DUMMY=$A8›:;›STA:DATA;STORE DATA›STY:SAVEY›LDY#$08›LDA#$FE›ANDDRB›STADRB;SET DATA BIT LOW›BIT:DUMMY›NOP›:FPUT3LSRA›LSR:DATA+$100›ROLA;PUT DATA BIT INTO D0 POSITION›STADRB›DEY›BNE:FPUT3;LOOP UNTIL OUT OF DATA›;›LSRA›SEC›ROLA;MAKE DATA BIT =1›NOP›BIT:DUMMY›STADRB›LDY:SAVEY›RTS›EPROC›FPVECDWFPUT›;›;›;**************************************›;›; CLRZER:›; CLEAR PAGE ZERO›;›; ENTRY:NONE›; EXIT: PAGE ZERO FILLED WITH $00›;›; REGISTERS USED :A,X›;›;**************************************›;›CLRZERLDA#$00;SET UP TO CLEAR MEM›TAX;INIT INDEX REGISTER›CLZER1STAZERO,X;CLEAR MEMORY BYTE›INX›CPX#$80›BNECLZER1;CONTINUE TILL DONE›RTS›;›;**************************************›;›; SDSTAT:›; SEND STATUS TO THE ATARI COMPT›;›; ENTRY:NONE›; EXIT: STATUS SENT TO ATARI›;›; REGISTERS USED:A,X›;›; MEMORY USED:SENDS STATUS BLOCK FROM›; PAGE ZERO SEE ABOVE›;›; FORMAT OF STATUS ARRAY:›; BYTE 0:COMMAND STATUS›; BYTE 1:HARDWARE STATUS›; BYTE 2:TIMEOUT›; BYTE 3:UNUSED›;›; COMMAND STATUS:›; BIT0=1 INDICATES INVALID CMD FRM REC›; BIT1=1 IND. INVALID DATA FRAME REC.›; BIT2=1 IND. PUT WAS UNSUCCESSFUL›; BIT3=1 IND. DISKET IS WRITE PROTECTED›; BIT4=1 IND ACTIVE STANDBY›; BIT5=1 IND DOUBLE DENSITY›;›; BIT7=1 IND DUAL DENSITY›;›; HARWARE STATUS = STAT REG OF 1793›;›; TIME OUT = MAX TIME HANDLER TO USE›;›;›;**************************************›;›SDSTATLDA#$00;INITIALIZE CHECKSUM›STACHKSUM›TAX;INIT INDEX REGISTER›SSTAT1LDASTAT,X;LOAD BYTE FROM›;STATUS ARRAY›JSRCSUM;CALCULATE CHECKSUM FOR XMIT›JSRPUT;SEND IT TO ATARI›INX›CPX#$04;SENT ALL FOUR BYTES?›BNESSTAT1›;›LDACHKSUM;LOAD CHECK SUM›JSRPUT;SEND IT TO ATARI TOO›RTS;RETURN›;›;›;**************************************›;›; READ:›; FILLS BUFFER ON PAGE TWO WITH›; 256 BYTES OF DATA SENT BY›; ATARI›;›; ENTRY:ACC=LENTH (0=256 BYTES)›; :BPNT= BUFFER AREA TO PUT DATA›; EXIT: BUFFER FILLED WITH DATA›; : $A0 STATUS OF OPERATION›; : 0=OK›; : 1=TIMEOUT›; : 2=CHECKSUM ERROR›;›; REGISTERS USED:A,X,Y›;›; MEMORY USED:PAGE 2›;›;**************************************›;›READPROC›:CHKS=$A1;CHECKSUM RETURNED FROM GET›:STATUS=$A0;STATUS RETURNED BY GET›:LEN=$A2;LENTH OF BUFFER TO SEND›;›STA:LEN›JSRGET;GET DATA FROM SIO BUS›LDA:STATUS;CHECK STATUS›BNE:RDXIT›LDA:CHKS›LDX:LEN;CHECK LEN BYTES›JSRCKSM›:RDXITRTS›EPROC›;›;›;**************************************›;›; SEND:›; SEND DATA IN PAGE 2 BUFFER BACK›; TO THE ATARI COMPUTER›;›; ENTRY:BPNT POINTS TO DATA TO SEND›; EXIT :DATA SENT TO ATARI›;›; REGISTERS USED:A,Y›;›; MEMORY USED:PAGE 2 AS MEMORY BUFFER›; :$A4›;**************************************›;›SENDPROC›;›:LEN=$A4›STA:LEN›LDA#$00;INITIALIZE CHECKSUM›STACHKSUM›TAY;INITIALIZE INDEX REGISTER›:SEND1LDA(BPNT),Y;LOAD DAT FROM BUFF›JSRCSUM;CALCULATE CHECK SUM›JSRPUT;SEND DATA TO ATARI›INY;NEXT MEMORY LOCATION TO SEND›CPY:LEN;COMPARE TO LENTH TO SEND›BNE:SEND1;SENT ALL 256 BYTES?›;›LDACHKSUM;LOAD CHECKSUM›JSRPUT;AND SEND IT ON ITS WAY›RTS;DONE›EPROC›;›LINKD2:DD15M2.ASM›%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%